package com.wxapp.admin.service.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.enums.SqlKeyword;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wxapp.admin.api.pojo.entity.UserCDJDO;
import com.wxapp.admin.api.pojo.entity.UserDO;
import com.wxapp.admin.api.pojo.entity.UserRoleDO;
import com.wxapp.admin.api.pojo.vm.user.PUserDetailVm;
import com.wxapp.admin.api.pojo.vm.user.PUserOtherVm;
import com.wxapp.admin.api.pojo.vm.user.PUserPageVm;
import com.wxapp.admin.api.pojo.vo.user.QUserPageVo;
import com.wxapp.admin.api.pojo.vm.userCDJ.PCDJDetailVm;
import com.wxapp.admin.api.pojo.vo.user.*;
import com.wxapp.admin.service.mapper.UserCDJMapper;
import com.wxapp.admin.service.mapper.UserMapper;
import com.wxapp.admin.service.mapper.UserRoleMapper;
import com.wxapp.admin.service.service.UserService;
import com.wxapp.common.constant.base.IBaseService;
import com.wxapp.common.constant.constant.CatchCommonConstant;
import com.wxapp.common.constant.pojo.vm.ResultVm;
import com.wxapp.common.constant.pojo.vo.UserVo;
import com.wxapp.common.util.check.CheckUtil;
import com.wxapp.common.util.condition.ConditionUtil;
import com.wxapp.common.util.copy.CopyUtil;
import com.wxapp.common.util.random.RandomUtil;
import com.wxapp.common.base.util.redis.RedisUtil;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author lgl
 */
@Service
@RequiredArgsConstructor
public class UserServiceImpl extends IBaseService implements UserService {
    private final UserMapper userMapper;
    private final UserRoleMapper userRoleMapper;
    private final UserCDJMapper userCDJMapper;
    private final RedisUtil redisUtil;
    @Override
    @GlobalTransactional
    public ResultVm<String> saveUser(UserVo userVo, QSaveVo qSaveVo) {
        LambdaQueryWrapper<UserDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserDO::getLoginName, qSaveVo.getLoginName()).eq(UserDO::getStatus, true);
        var userCount = userMapper.selectCount(wrapper);
        if (userCount > 0) {
            return error("用户名已存在！！");
        }
        var incr = redisUtil.incr(CatchCommonConstant.USER_CODE, 1);
        UserDO userDO = CopyUtil.copyObjectNew(qSaveVo, UserDO::new, (s, r) -> {
            String salt = RandomUtil.getAllRandom(6);
            var password = RandomUtil.md5BySalt("admin123456", salt);
            r.setSalt(salt);
            r.setCode(String.valueOf(incr));
            r.setCreateBy(userVo.getId());
            r.setPassword(password);
            return null;
        });
        userMapper.insert(userDO);
        saveCDJ(userVo, qSaveVo, userDO.getId());
        return success();
    }



    @Override
    public ResultVm<PUserDetailVm> detailUser(UserVo userVo) {
        PUserDetailVm pGetUserDetailVo = new PUserDetailVm();
        LambdaQueryWrapper<UserDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserDO::getStatus, true).eq(CheckUtil.isNotNullObject(userVo.getId()), UserDO::getId, userVo.getId());
        UserDO userDO = userMapper.selectFirst(wrapper);
        CopyUtil.copyObject(userDO, pGetUserDetailVo, null);
        PCDJDetailVm pcdjDetailVm = userRoleMapper.getCDJDetail(userVo.getId());
        if (CheckUtil.isNotNullObject(pcdjDetailVm)) {
            pGetUserDetailVo.setDept(CheckUtil.isNotNullObject(pcdjDetailVm.getDeptId()) ? new PUserOtherVm(pcdjDetailVm.getDeptId(), pcdjDetailVm.getDeptName()) : null);
            pGetUserDetailVo.setJob(CheckUtil.isNotNullObject(pcdjDetailVm.getJobId()) ? new PUserOtherVm(pcdjDetailVm.getJobId(), pcdjDetailVm.getJobName()) : null);
            pGetUserDetailVo.setCompany((CheckUtil.isNotNullObject(pcdjDetailVm.getCompanyId()) ? new PUserOtherVm(pcdjDetailVm.getCompanyId(), pcdjDetailVm.getCompanyName()) : null));
        }
        pGetUserDetailVo.setRoleList(userRoleMapper.getRoleList(userVo.getId()));
        return success("获取用户信息成功", pGetUserDetailVo);
    }

    @Override
    public ResultVm<String> updateUser(UserVo userVo, QUserUpdateVo qSaveVo) {
        LambdaQueryWrapper<UserDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserDO::getId, qSaveVo.getId()).eq(UserDO::getStatus, true);
        var userCount = userMapper.selectFirst(wrapper);
        if (CheckUtil.isNullObject(userCount)) {
            return error("用户信息不存在！！");
        }
        CopyUtil.copyObject(qSaveVo, userCount, null);
        userMapper.updateById(userCount);
        LambdaUpdateWrapper<UserRoleDO> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(UserRoleDO::getUserId, qSaveVo.getId());
        userRoleMapper.delete(updateWrapper);
        saveCDJ(userVo, qSaveVo, qSaveVo.getId());
        return success("更新成功");
    }

    @Override
    public ResultVm<Page<PUserPageVm>> pageUser(QUserPageVo qSaveVo) {
        Map<SFunction<UserDO, ?>, SqlKeyword> conditions = new HashMap<>();
        conditions.put(UserDO::getLoginName, SqlKeyword.LIKE);
        var sCondition = ConditionUtil.getSCondition(UserDO::new, qSaveVo, null, conditions,null);
        var page = ConditionUtil.getPage(qSaveVo, UserDO.class);
        var selectPage = userMapper.selectPage(page, sCondition);
        return success(CopyUtil.copyPage(selectPage, PUserPageVm::new, null));
    }

    @Override
    public ResultVm<String> deleteUser(String id) {
        var user = userMapper.selectById(id);
        user.setStatus(false);
        userMapper.updateById(user);
        return success("删除成功");
    }

    @Override
    public ResultVm<String> updatePw(UserVo userVo, QUpdatePwVo qUpdatePwVo) {
        var userDO = userMapper.selectById(userVo.getId());
        if (!(RandomUtil.md5BySalt(qUpdatePwVo.getOldPassword(), userDO.getSalt())).equals(userDO.getPassword())) {
            return error("老密码不正确");
        }
        if (!qUpdatePwVo.getConformPassword().equals(qUpdatePwVo.getPassword())) {
            return error("密码和确认密码不一致");
        }
        String salt = RandomUtil.getAllRandom(6);
        userDO.setPassword(RandomUtil.md5BySalt(qUpdatePwVo.getPassword(), salt));
        userDO.setSalt(salt);
        userDO.setUpdateBy(userVo.getId());
        userMapper.updateById(userDO);
        return success("修改密码成功");
    }

    @Override
    public ResultVm<String> updateAvatar(UserVo userVo, QUpdateAvatarVo qSaveVo) {
        LambdaUpdateWrapper<UserDO> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(UserDO::getId, userVo.getId()).eq(UserDO::getStatus, true).set(CheckUtil.isNotNullString(qSaveVo.getAvatarUrl()), UserDO::getAvatar, qSaveVo.getAvatarUrl()).set(CheckUtil.isNotNullString(qSaveVo.getNickName()), UserDO::getNickName, qSaveVo.getNickName());
        userMapper.update(null, wrapper);
        return success("更新成功");
    }

    private void saveCDJ(UserVo userVo, QSaveVo qSaveVo, String id) {
        saveUserRole(qSaveVo.getRoleList(), id, userVo);
        LambdaQueryWrapper<UserCDJDO> userQuery = new LambdaQueryWrapper<>();
        userQuery.eq(UserCDJDO::getStatus, true).eq(UserCDJDO::getUserId, id);
        if (userCDJMapper.selectCount(userQuery) > 0) {
            LambdaUpdateWrapper<UserCDJDO> userCDWrapper = new LambdaUpdateWrapper<>();
            userCDWrapper.eq(UserCDJDO::getStatus, true).eq(UserCDJDO::getUserId, id).set(UserCDJDO::getCompanyId, qSaveVo.getCompanyId()).set(UserCDJDO::getDeptId, qSaveVo.getDeptId()).set(UserCDJDO::getJobId, qSaveVo.getJobId());
            userCDJMapper.update(null, userCDWrapper);
        } else {
            UserCDJDO userCDJDO = new UserCDJDO();
            userCDJDO.setUserId(id);
            userCDJDO.setCompanyId(qSaveVo.getCompanyId());
            userCDJDO.setDeptId(qSaveVo.getDeptId());
            userCDJDO.setJobId(qSaveVo.getJobId());
            userCDJDO.setCreateBy(userVo.getId());
            userCDJMapper.insert(userCDJDO);
        }
    }
    private void saveUserRole(List<QUserOtherVo> roles, String userId, UserVo userVo) {
        if (CheckUtil.isNotNullList(roles)) {
            List<UserRoleDO> userRoles = new ArrayList<>();
            roles.forEach(s -> {
                UserRoleDO userRoleDO = new UserRoleDO();
                userRoleDO.setUserId(userId);
                userRoleDO.setRoleId(s.getId());
                userRoleDO.setCreateBy(userVo.getId());
                userRoles.add(userRoleDO);
            });
            if (CheckUtil.isNotNullList(userRoles)) {
                userRoleMapper.insertBatch(userRoles);
            }
        }
    }
}
